package com.cmdi.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.captcha.generator.MathGenerator;
import com.cmdi.constant.CodeConstants;
import com.cmdi.constant.CommonConstants;
import com.cmdi.constant.SecurityConstants;
import com.cmdi.domain.LoginResult;
import com.cmdi.domain.R;
import com.cmdi.log.annotation.SysLog;
import com.cmdi.service.SysLoginService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.security.Principal;

/**
 * @Description: java类作用描述
 * @Author: gaozb
 */
@Slf4j
@RestController
@Api(tags = "用户管理")
public class LoginController {
    private final static MathGenerator MATH_GENERATOR = new MathGenerator(1);
    @Autowired
    private SysLoginService sysLoginService;
    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/captcha")
    @ApiOperation("验证码")
    public void captcha(HttpSession session, HttpServletResponse response) {

        ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(100, 50,4,0);
        shearCaptcha.setGenerator(MATH_GENERATOR);

        String code = shearCaptcha.getCode();
        session.setAttribute(SecurityConstants.CAPTCHA_CODE_KEY, code);
        ServletOutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            shearCaptcha.write(outputStream);
            log.info("code:{}", code);
        } catch (IOException e) {
            log.error(e.getMessage());
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }
    }

    @PostMapping("/login")
    @ApiOperation("登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名称"),
            @ApiImplicitParam(name = "password", value = "用户的密码"),
            @ApiImplicitParam(name = "kaptchaCode", value = "验证码"),
            @ApiImplicitParam(name = "logintype", value = "登录类型，admin/user"),
    })
    @SysLog("用户登录")
    public R<LoginResult> login(@RequestParam(required = true) String username,
                             @RequestParam(required = true) String password,
                             @RequestParam(required = true) String kaptchaCode,
                             @RequestParam(required = true) String logintype,
                             HttpSession session) {
        Object captcha = session.getAttribute(SecurityConstants.CAPTCHA_CODE_KEY);
        if(captcha == null) {
            return R.fail("验证码错误");
        }
        String realCode = (String) captcha;

        log.info("Input-Captcha:{}, Real-Captcha:{}", kaptchaCode, realCode);

        boolean verify = MATH_GENERATOR.verify(realCode, kaptchaCode);

        return verify ? R.ok(sysLoginService.login(username, password, logintype)) : R.fail("验证码错误");
    }

    @PostMapping("/refreshtoken")
    @ApiOperation("token续签")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "refreshtoken", value = "token续签"),
            @ApiImplicitParam(name = "logintype", value = "登录类型，admin/user")
    })
    //@SysLog("token续签")
    public R<LoginResult> refreshtoken(@RequestParam(required = true) String refreshtoken,
                                       @RequestParam(required = true) String logintype ) {

        return R.ok(sysLoginService.refreshToken(refreshtoken, logintype));
    }

    @ApiOperation("退出登录")
    @GetMapping("/out")
    public R logout(HttpServletRequest request, Principal principal) {
        if(principal != null) {
            String authorization = request.getHeader("Authorization");
            String token = authorization.replaceAll("bearer ", "");
            String name = principal.getName();
            String key = SecurityConstants.TOKEN_REDIS_PREFIX + ":" +  name + ":" + token;

            if(redisTemplate.hasKey(key)) {
                if(redisTemplate.delete(key)) {
                    return R.ok(null, "退出登录成功");
                }
            } else {
                return R.ok(null,"未登录");
            }
        } else {
            return R.ok(null,"未登录");
        }
        return R.ok(null,"未登录");
    }

    @ApiOperation("测试1")
    @GetMapping("/test1")
    @PreAuthorize("hasAuthority('cash_withdraw_audit_1')")
    public R<String> test1() {
        return R.ok("123");
    }

    @ApiOperation("测试2")
    @GetMapping("/test2")
    @PreAuthorize("hasAuthority('cash_withdraw_audit_888')")
    public R<String> test2() {
        return R.ok("123");
    }

}